package com.yanqu.road.server.manger.config.grandchild;

import com.yanqu.road.dao.impl.player.GrandChildDataDaoImpl;
import com.yanqu.road.entity.grandchild.GrandChildData;
import com.yanqu.road.entity.grandchild.GrandChildExamResult;
import com.yanqu.road.entity.grandchild.GrandChildUserExam;
import com.yanqu.road.logic.bussiness.grandchild.GrandChildBussiness;
import com.yanqu.road.logic.thread.ThreadTaskManger;
import com.yanqu.road.pb.grandchild.GrandChildProto;
import com.yanqu.road.server.TempMgr;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.grandson.GrandChildModule;
import com.yanqu.road.server.manger.player.UserMgr;
import com.yanqu.road.server.manger.player.GamePlayerMgr;
import com.yanqu.road.server.protocol.ClientProtocol;
import com.yanqu.road.utils.executor.GeneralTask;
import org.apache.mina.util.ConcurrentHashSet;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

public class GrandChildMgr extends TempMgr {

    // 暂存科举结果
    private static Map<Long, GrandChildUserExam> userExamMap;
    // 暂存已处理科举
    private static final Set<String> handleExamSet = new ConcurrentHashSet<>();

    //做个线程池给耗时的请求跑
    private static ThreadTaskManger threadTaskManger;
    private static AtomicInteger taskId = new AtomicInteger(1);

    // 获取玩家科举结果
    private static GrandChildUserExam getUserGrandChildExam(long userId) {
        if (!userExamMap.containsKey(userId)) {
            synchronized (userExamMap) {
                if (!userExamMap.containsKey(userId)) {
                    GrandChildUserExam exam = new GrandChildUserExam(userId, new ArrayList<>(), "");
                    exam.setInsertOption();
                    userExamMap.put(userId, exam);
                }
            }
        }
        return userExamMap.get(userId);
    }

    // 添加未发奖科举
    private static void addUserExamResult(long userId, GrandChildExamResult result) {
        GrandChildUserExam exam = getUserGrandChildExam(userId);
        synchronized (exam) {
            exam.getResultList().add(result);
            exam.setUpdateOption();
        }
    }

    // 添加未读科举
    private static void addUserNoReadExam(long userId, String examNo) {
        GrandChildUserExam exam = getUserGrandChildExam(userId);
        exam.setNoReadNo(examNo);
    }

    /**
     * 同步未读科举编号
     */
    public static void syncNoReadExamNo(GamePlayer player) {
        GrandChildUserExam exam = getUserGrandChildExam(player.getUserId());
        GrandChildProto.SyncNoReadExamNoRespMsg.Builder builder = GrandChildProto.SyncNoReadExamNoRespMsg.newBuilder();
        builder.setExamNo(exam.getNoReadNo());
        player.sendPacket(ClientProtocol.U_GRAND_CHILD_SYNC_NO_READ_EXAM, builder);
    }

    /**
     * 添加科举结果
     */
    public static void handleExamResult(GrandChildProto.CrossSyncExamFinishMsg msg) {
        String examNo = msg.getNo();
        long finishTime = msg.getFinishTime();

        // 避免重复结算
        synchronized (handleExamSet) {
            if (handleExamSet.contains(msg.getNo())) {
                return;
            }
            handleExamSet.add(msg.getNo());
        }

        // 玩家ID，孙子ID，title
        Map<Long, Map<String, Integer>> map = new ConcurrentHashMap<>();
        for (GrandChildProto.ExamPupilResultMsg resultMsg : msg.getResultList()) {
            if (!map.containsKey(resultMsg.getUserId())) {
                map.put(resultMsg.getUserId(), new ConcurrentHashMap<>());
            }
            map.get(resultMsg.getUserId()).put(resultMsg.getId(), resultMsg.getTitle());
        }

        for (Map.Entry<Long, Map<String, Integer>> entry : map.entrySet()) {
            long userId = entry.getKey();

            // 不是本服的跳过
            if (UserMgr.getLastLoginTime(userId) == 0) {
                continue;
            }

            Map<String, Integer> titleMap = entry.getValue();
            GrandChildExamResult result = new GrandChildExamResult();
            result.setNo(examNo);
            result.setTime(finishTime);
            result.setMap(titleMap);

            // 添加科举未领奖
            addUserExamResult(userId, result);

            // 设置未读
            addUserNoReadExam(userId, examNo);
        }

        // 在线玩家检查未领取奖励
        for (GamePlayer gamePlayer : GamePlayerMgr.getAllOnlinePlayer()) {
            gamePlayer.getModule(GrandChildModule.class).checkExamReward();
        }
    }

    /**
     * 获取科举结果
     */
    public static List<GrandChildExamResult> getExamResultAndRemove(GamePlayer player) {
        GrandChildUserExam exam = getUserGrandChildExam(player.getUserId());

        List<GrandChildExamResult> resultList;
        synchronized (exam) {
            resultList = new ArrayList<>(exam.getResultList());
            exam.getResultList().clear();
            exam.setUpdateOption();
        }
        return resultList;
    }

    /**
     * 观看科举结果
     */
    public static void readUserExamResult(GamePlayer player, String examNo) {
        GrandChildUserExam exam = getUserGrandChildExam(player.getUserId());
        if (Objects.equals(examNo, exam.getNoReadNo())) {
            exam.setNoReadNo("");
            syncNoReadExamNo(player);
        }
    }

    @Override
    public boolean save() {
        // 未读科举
        for (GrandChildUserExam data : userExamMap.values()) {
            if (data.isInsertOption()) {
                GrandChildBussiness.addGrandChildUserExam(data);
            } else if (data.isUpdateOption()) {
                GrandChildBussiness.updateGrandChildUserExam(data);
            }
        }

        return true;
    }

    @Override
    public boolean init() throws Exception {
        return reload();
    }

    @Override
    public boolean reloadConfig() throws Exception {
        return true;
    }

    @Override
    public boolean reloadData() throws Exception {
        if(null == threadTaskManger) {
            threadTaskManger = new ThreadTaskManger(1, "GrandChildMgr");
        }
        userExamMap = GrandChildBussiness.getGrandChildUserExamMap();
        return true;
    }

    @Override
    public boolean stop() {
        return true;
    }

    public static void addTask(GeneralTask task) {
        threadTaskManger.addTask(taskId.getAndIncrement(), task);
    }

    public static GrandChildData getGrandChildData(long userId, String id){
        GrandChildData grandChildData = null;
        GamePlayer player = GamePlayerMgr.getOnlinePlayer(userId);
        if(null != player){
            grandChildData = player.getModule(GrandChildModule.class).getGrandChild(id);
        }
        if(null == grandChildData){
            grandChildData = new GrandChildDataDaoImpl().getGrandChildData(userId, id);
        }
        return grandChildData;
    }
}
